<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta http-equiv="x-ua-compatible" content="ie=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="favicon.ico" type="image/x-icon"/>
  <link rel="stylesheet" href="examples-styles.css"/>

	<title>Karaoke Synth</title>

	<style>
		main {
			max-width: 770px;
			margin: 0 auto;
		}
    .buttons {
      text-align: center;
    }
	</style>

	<script src="../dist/abcjs-basic.js" type="text/javascript"></script>
	<script type="text/javascript">
		var abc =
			'T:Cindy\n' +
			'M:4/4\n' +
			'K:G\n' +
			'%%score (harmony melody)\n' +
			'L:1/4\n' +
				'[V: harmony]' +
			'g||"G"gggg|dB2g|gggd|g3g|\n' +
			'"G"gggd|dcB2|dccA|Bzz2|\n' +
			'"C"G2cc|ccd/c/B|"G"G4-|Gzz2|\n' +
			'"C"G2cc|cc2c|"D7"dddc|"G"B2z2|]\n' +
				'[V: melody]' +
			'd||"G"eddB|AG2d|eddB|d3d|\n' +
			'"G"eddB|BAG2|"D7"BGGE|"G"GzB/A/G|\n' +
			'"C"E2GG|AGB/A/G|"G"D4-|DzB/A/G|\n' +
			'"C"E2GG|AG2A|"D7"BBBA|"G"G2z2|]\n';

		function load() {
			// First draw the music - this supplies an object that has a lot of information about how to create the synth.
			var visualObj = ABCJS.renderAbc("paper", abc, {
				responsive: "resize" })[0];

			// This object is the class that will contain the buffer
			var midiBuffer;

			var startChordsButton = document.querySelector(".play-chords");
			var startMelodiesButton = document.querySelector(".play-melodies");
			var startHarmonyButton = document.querySelector(".play-harmony");
			var startMelodyButton = document.querySelector(".play-melody");
			var startAllButton = document.querySelector(".play-all");
			var stopAudioButton = document.querySelector(".stop-audio");

			startChordsButton.addEventListener("click", function() {
				var options = {voicesOff: true};
				play(options);
			});

			startMelodiesButton.addEventListener("click", function() {
				var options = {chordsOff: true};
				play(options);
			});

			startHarmonyButton.addEventListener("click", function() {
				var options = {chordsOff: true, voicesOff: [1]};
				play(options);
			});

			startMelodyButton.addEventListener("click", function() {
				var options = {chordsOff: true, voicesOff: [0]};
				play(options);
			});

			startAllButton.addEventListener("click", function() {
				var options = {};
				play(options);
			});

			function play(options) {
				startChordsButton.setAttribute("style", "display:none;");
				startMelodiesButton.setAttribute("style", "display:none;");
				startHarmonyButton.setAttribute("style", "display:none;");
				startMelodyButton.setAttribute("style", "display:none;");
				startAllButton.setAttribute("style", "display:none;");
				if (ABCJS.synth.supportsAudio()) {
					stopAudioButton.setAttribute("style", "");

					// An audio context is needed - this can be passed in for two reasons:
					// 1) So that you can share this audio context with other elements on your page.
					// 2) So that you can create it during a user interaction so that the browser doesn't block the sound.
					// Setting this is optional - if you don't set an audioContext, then abcjs will create one.
					window.AudioContext = window.AudioContext ||
						window.webkitAudioContext ||
						navigator.mozAudioContext ||
						navigator.msAudioContext;
					var audioContext = new window.AudioContext();
					audioContext.resume().then(function () {
						// In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway.

						// This does a bare minimum so this object could be created in advance, or whenever convenient.
						midiBuffer = new ABCJS.synth.CreateSynth();

						// midiBuffer.init preloads and caches all the notes needed. There may be significant network traffic here.
						return midiBuffer.init({
							visualObj: visualObj,
							audioContext: audioContext,
							millisecondsPerMeasure: visualObj.millisecondsPerMeasure(),
							options: options

						}).then(function (response) {
							// console.log(response); // this contains the list of notes that were loaded.
							// midiBuffer.prime actually builds the output buffer.
							return midiBuffer.prime();
						}).then(function () {
							// At this point, everything slow has happened. midiBuffer.start will return very quickly and will start playing very quickly without lag.
							midiBuffer.start();
							return Promise.resolve();
						}).catch(function (error) {
							if (error.status === "NotSupported") {
								stopAudioButton.setAttribute("style", "display:none;");
								var audioError = document.querySelector(".audio-error");
								audioError.setAttribute("style", "");
							} else
								console.warn("synth error", error);
						});
					});
				} else {
					var audioError = document.querySelector(".audio-error");
					audioError.setAttribute("style", "");
				}
			}

			stopAudioButton.addEventListener("click", function() {
				startChordsButton.setAttribute("style", "");
				startMelodiesButton.setAttribute("style", "");
				startHarmonyButton.setAttribute("style", "");
				startMelodyButton.setAttribute("style", "");
				startAllButton.setAttribute("style", "");
				stopAudioButton.setAttribute("style", "display:none;");
				if (midiBuffer)
					midiBuffer.stop();
			});
		}
	</script>
</head>
<body onload="load()">
  <header>
    <img src="https://paulrosen.github.io/abcjs/img/abcjs_comp_extended_08.svg" alt="abcjs logo">
    <h1>abcjs karaoke synth</h1>
  </header>
  <div class="container">
    <main>
      <div id="paper"></div>
      <div class="buttons">
        <button class="play-chords">Play Chords</button>
        <button class="play-melodies">Play Melodies</button>
        <button class="play-harmony">Play Harmony</button>
        <button class="play-melody">Play Melody</button>
        <button class="play-all">Play All</button>
        <button class="stop-audio" style="display:none;">Stop Audio</button>
      </div>
      <div class='audio-error' style="display:none;">Audio is not supported in this browser.</div>
    </main>
  </div>
</body>
</html>
